home *** CD-ROM | disk | FTP | other *** search
/ Shareware Grab Bag / Shareware Grab Bag.iso / 090 / forlib1.arc / DOW.ASM < prev    next >
Assembly Source File  |  1986-01-16  |  10KB  |  228 lines

  1. DATA SEGMENT PUBLIC 'DATA'
  2. TITLE__        DB  'TITLE: DAY OF WEEK FOR MS FORTRAN'
  3. COPY_R         DB  '   (C) John R. Petrocelli'
  4.                DB  '       Schenectady,NY    '
  5.                DB  '       01/16/86          '
  6.  
  7. INITIAL_YEAR   EQU  1901            ; 1901 INITIAL YEAR
  8. INITIAL_DAY    EQU  3-1             ; TUESDAY  01/01/1901 CORRECTED
  9.                                     ; (-1) FOR COMPUTATION SINCE WE
  10.                                     ; MUST START WITH 0
  11. MAX_YEAR       EQU  2099            ; HIGHEST YEAR WE CAN CALCULATE
  12.                                     ; FOR THIS ROUTINE
  13.  
  14.                                     ; *** NOTE ***
  15.                                     ; A CENTURY IS ONLY A LEAP YEAR
  16.                                     ; IF IT IS EVENLY DIVISIBLE BY
  17.                                     ; 400. THEREFORE THE YEAR 2000
  18.                                     ; IS A LEAP YEAR.
  19.  
  20. LEAP_YEAR_OFF  EQU  0
  21. LEAP_YEAR_ON   EQU  1
  22. CR             EQU  0DH             ; CARRAGE RETURN
  23. LF             EQU  0AH             ; LINE FEED
  24. EOM            EQU  '$'             ; END OF MESSAGE INDICATOR
  25.  
  26. ERR_MSG_HDR    DB CR,LF,'WEEKDY SUBROUTINE PARAMETER ERROR',EOM
  27. ERR_MSG_YR     DB CR,LF,'YEAR MUST BE > 1901 AND < 2099',CR,LF,EOM
  28. ERR_MSG_MO     DB CR,LF,'MONTH LESS THAN 1 OR GREATER THAN 12',CR,LF,EOM
  29. ERR_MSG_DY     DB CR,LF,'DAY LESS THAN 1 OR GREATER '
  30.                DB CR,LF,'THAN # OF DAYS IN SPECIFIED MONTH',CR,LF,EOM
  31.  
  32. LEAP_YR        DW   0
  33. YEAR           DW   0
  34. MONTH          DW   0
  35. DAY            DW   0
  36. WEEK_DY        DW   0
  37. XLAT_MONTH     DB   31,28,31        ;JAN,FEB,MAR
  38.                DB   30,31,30        ;APR,MAY,JUN
  39.                DB   31,31,30        ;JUL,AUG,SEP
  40.                DB   31,30,31        ;OCT,NOV,DEC
  41.                DB   29              ;FEB  IN LEAP YEAR
  42.  
  43. DATA ENDS
  44. DGROUP GROUP DATA
  45. CODE   SEGMENT 'CODE'
  46.        ASSUME CS:CODE,DS:DGROUP,SS:DGROUP
  47. PUBLIC WEEKDY
  48. WEEKDY PROC  FAR
  49.        PUSH  BP                      ; SAVE FRAME POINTER
  50.        PUSH  AX                      ; SAVE REGISTERS
  51.        PUSH  BX
  52.        PUSH  DX
  53.        MOV   BP,SP                   ; FRAME POINTER POINTS TO STACK PTR
  54.  
  55.        MOV   WEEK_DY,INITIAL_DAY     ; SETUP INITIAL VALUES
  56.        MOV   LEAP_YR,LEAP_YEAR_OFF
  57.  
  58.        LES   BX,DWORD PTR[BP+24]     ; ES:BX POINTS TO MONTH
  59.        MOV   AX,[BX]                 ; GET MONTH INTO AX
  60.        MOV   MONTH,AX                ; STORE MONTH
  61.  
  62.        LES   BX,DWORD PTR[BP+20]     ; ES:BX POINTS TO DAY
  63.        MOV   AX,[BX]                 ; GET DAY IN AX
  64.        MOV   DAY,AX                  ; STORE DAY
  65.  
  66.        LES   BX,DWORD PTR[BP+16]     ; ES:BX POINTS TO YEAR
  67.        MOV   AX,[BX]                 ; GET YEAR INTO AX
  68.        MOV   YEAR,AX                 ; STORE YEAR
  69.  
  70.        CMP   AX,INITIAL_YEAR         ; COMPARE YEAR WITH THE LOWEST WE
  71.                                      ; CAN PROCESS
  72.        JAE   GOOD_LOW                ; JUMP IF GOOD YEAR
  73.        JMP   ERROR_YR                ; JUMP TO ERROR IF TOO LOW A YEAR
  74. GOOD_LOW:
  75.        CMP   AX,MAX_YEAR             ; COMPARE YEAR WITH THE HIGHEST WE
  76.                                      ; CAN PROCESS
  77.        JBE   GOOD_YEAR               ; JUMP IF YEAR IN OUR RANGE OF CALC
  78.        JMP   ERROR_YR                ; JUMP TO ERROR IF TOO HIGH A YEAR
  79. GOOD_YEAR:
  80.        MOV   BX,4                    ; LEAP YEAR DIVISOR
  81.        MOV   DX,0
  82.        DIV   BX                      ; DIVIDE YEAR BY 4
  83.        CMP   DX,0                    ; IS REMAINDER 0 ?
  84.        JNE   NOT_LEAP_REQ            ; JUMP IF NOT LEAP YEAR
  85.        MOV   LEAP_YR,LEAP_YEAR_ON    ; SET LEAP YEAR FLAG SINCE REQUEST
  86.                                      ; IS LEAP YEAR
  87.  
  88. ; -------------------------------------------------------------------
  89. ;  PROCESS YEAR
  90. ; -------------------------------------------------------------------
  91. NOT_LEAP_REQ:
  92.  
  93.        MOV   AX,INITIAL_YEAR         ; PUT START YEAR IN AX
  94. CHK_YR:
  95.        CMP   AX,YEAR                 ; IS AX EQUAL TO REQUESTED YEAR
  96.        JE    CHK_MONTH               ; IF YES CHECK DAY COUNT
  97.        PUSH  AX                      ; SAVE THE WORKING YEAR
  98.        MOV   BX,4                    ; LEAP YEAR DIVISOR
  99.        MOV   DX,0
  100.        DIV   BX                      ; DIVIDE YEAR BY 4
  101.        MOV   AX,365                  ; 365 DAYS/YR IN AX
  102.        CMP   DX,0                    ; IS REMAINDER 0 ?
  103.        JNE   NOT_LEAP_YR             ; JUMP IF NOT LEAP YEAR
  104.        INC   AX                      ; INCREMENT AX IF LEAP YEAR-366 DY
  105.  
  106. NOT_LEAP_YR:
  107.        MOV   BX,7                    ; DAY OF WEEK DIVISOR
  108.        MOV   DX,0
  109.        DIV   BX                      ; DIVIDE TO GET WEEKDAY OFFSET
  110.                                      ; IN DX
  111.        ADD   DX,WEEK_DY              ; ADD CURRENT DAY OF WEEK TO
  112.                                      ; WEEKDAY OFFSET
  113.        CMP   DX,8                    ; IS IT GREATER THAN 7 ?
  114.        JL    OK_DAY1                 ; NO THEN OK
  115.        SUB   DX,7                    ; YES THEN SUBTRACT 7
  116. OK_DAY1:
  117.        MOV   WEEK_DY,DX              ; SAVE RESULTING DAY OF WEEK
  118.  
  119.        POP   AX                      ; GET BACK VALUE OF AX
  120.        INC   AX                      ; ADD 1 TO AX FOR NEXT YEAR
  121.        JMP   CHK_YR                  ; DO AGAIN
  122.  
  123. ; -------------------------------------------------------------------
  124. ;  PROCESS MONTH
  125. ; -------------------------------------------------------------------
  126. CHK_MONTH:
  127.        MOV   AX,1                    ; PUT START MONTH IN AX
  128.        CMP   MONTH,AX                ; CHECK IF MONTH < 0
  129.        JAE   CHK_MO                  ; JUMP IF OK
  130.        JMP   ERROR_MO                ; JUMP IF ERROR
  131. CHK_MO:
  132.        CMP   AX,MONTH                ; IS AX EQUAL TO REQUESTED YEAR
  133.        JE    CHK_DAY                 ; IF YES CHECK DAY COUNT
  134.        PUSH  AX                      ; SAVE THE WORKING YEAR
  135.        CMP   AX,2                    ; ARE WE COMPUTING FEBRUARY DAYS ?
  136.        JNE   NO_FEBRUARY             ; NO - JUMP OVER
  137.        CMP   LEAP_YR,0               ; YES - IS LEAP YEAR FLAG SET ?
  138.        JZ    NO_FEBRUARY             ; NO - JUMP OVER
  139.        ADD   AX,11                   ; ADD AX WITH OFFSET FOR TRANSLATE
  140. NO_FEBRUARY:
  141.        LEA   BX,XLAT_MONTH           ; BX POINTS TO TRANSLATE TABLE
  142.        DEC   AX                      ; CORRECT AX FOR TABLE START
  143.        XLAT  XLAT_MONTH              ; TRANSLATE - AX HAS DAYS IN MONTH
  144.  
  145.        MOV   BX,7                    ; DAY OF WEEK DIVISOR
  146.        MOV   DX,0
  147.        DIV   BX                      ; DIVIDE TO GET WEEKDAY OFFSET
  148.                                      ; IN DX
  149.        ADD   DX,WEEK_DY              ; ADD CURRENT DAY OF WEEK TO
  150.                                      ; WEEKDAY OFFSET
  151.        CMP   DX,8                    ; IS IT GREATER THAN 7 ?
  152.        JL    OK_DAY2                 ; NO THEN OK
  153.        SUB   DX,7                    ; YES THEN SUBTRACT 7
  154. OK_DAY2:
  155.        MOV   WEEK_DY,DX              ; SAVE RESULTING DAY OF WEEK
  156.  
  157.        POP   AX                      ; GET BACK VALUE OF AX
  158.        INC   AX                      ; ADD 1 TO AX FOR NEXT MONTH
  159.        JMP   CHK_MO                  ; DO AGAIN
  160.  
  161.  
  162. ; -------------------------------------------------------------------
  163. ;  PROCESS DAY
  164. ; -------------------------------------------------------------------
  165. CHK_DAY:
  166.        CMP   AX,2                    ; ARE WE ASKING FOR FEBRUARY DAYS ?
  167.        JNE   NOT_IN_FEB              ; NO - JUMP OVER
  168.        CMP   LEAP_YR,0               ; YES - IS LEAP YEAR FLAG SET ?
  169.        JZ    NOT_IN_FEB              ; NO - JUMP OVER
  170.        ADD   AX,11                   ; ADD AX WITH OFFSET FOR TRANSLATE
  171. NOT_IN_FEB:
  172.        LEA   BX,XLAT_MONTH           ; BX POINTS TO TRANSLATE TABLE
  173.        DEC   AX                      ; CORRECT AX FOR TABLE START
  174.        XLAT  XLAT_MONTH              ; TRANSLATE - AX HAS DAYS IN MONTH
  175.        CMP   DAY,AX                  ; BE SURE DAY NOT > DAYS IN MONTH
  176.        JA    ERROR_DY                ; JUMP IF ERROR
  177.        MOV   AX,DAY                  ; PUT REQUESTED DAY IN AX
  178.  
  179.        MOV   BX,7                    ; DAY OF WEEK DIVISOR
  180.        MOV   DX,0
  181.        DIV   BX                      ; DIVIDE TO GET WEEKDAY OFFSET
  182.                                      ; IN DX
  183.        ADD   DX,WEEK_DY              ; ADD CURRENT DAY OF WEEK TO
  184.                                      ; WEEKDAY OFFSET
  185.        CMP   DX,8                    ; IS IT GREATER THAN 7 ?
  186.        JL    OK_DAY3                 ; NO THEN OK
  187.        SUB   DX,7                    ; YES THEN SUBTRACT 7
  188. OK_DAY3:
  189.        MOV   WEEK_DY,DX              ; SAVE RESULTING DAY OF WEEK
  190.  
  191.  
  192. ; -------------------------------------------------------------------
  193. ;  WE NOW KNOW WHAT DAY OF THE WEEK IT IS
  194. ; -------------------------------------------------------------------
  195.        LES   BX,DWORD PTR[BP+12]     ; ES:BX POINTS TO RETURN VALUE
  196.                                      ; FOR DAY OF WEEK
  197.        MOV   AX,WEEK_DY              ; GET DAY OF WEEK INTO AX
  198.        MOV   [BX],AX                 ; STOW IT FOR RETURN
  199.        JMP   BYE                     ; JUMP OVER ERROR REPORTS
  200. ERROR_YR:
  201.        LEA   DX,ERR_MSG_YR           ; BAD YEAR ERROR MESSAGE
  202.        JMP   MESSAGE
  203. ERROR_MO:
  204.        LEA   DX,ERR_MSG_MO           ; BAD MONTH ERROR MESSAGE
  205.        JMP   MESSAGE
  206. ERROR_DY:
  207.        LEA   DX,ERR_MSG_DY           ; BAD DAY ERROR MESSAGE
  208. MESSAGE:
  209.        PUSH  DX                      ; SAVE ERROR MSG ADDRESS
  210.        LEA   DX,ERR_MSG_HDR          ; DX POINTS TO ERROR MSG HEADER
  211.        MOV   AX,0900H                ; LOAD AX WITH PRINT FUNCTION
  212.        INT   21H                     ; PRINT MESSAGE
  213.        POP   DX                      ; RESTORE ERROR MSG ADDRESS
  214.        MOV   AX,0900H                ; LOAD AX WITH PRINT FUNCTION
  215.        INT   21H                     ; PRINT MESSAGE
  216.  
  217. BYE:
  218.        POP   DX                      ; RESTORE REGISTERS
  219.        POP   BX
  220.        POP   AX
  221.        POP   BP                      ; RESTORE FRAME POINTER
  222.        RET   16                      ; RETURN AND POP 16 BYTES OFF
  223.                                      ; STACK
  224.        WEEKDY ENDP
  225.  
  226.        CODE ENDS
  227. END
  228.